'''
Created on 13/05/2009

@author: Edward
'''
from Queue import PriorityQueue

class IdentityMap(object):
    '''
    Differs from the traditional identity map pattern as it is not
    session-specific. It is used by the Datastore cache in a global context
    across all sessions. The job of the IdentityMap is to store dsos in memory
    to prevent multiple database calls for the same dso. The dso returned is always
    the same instance. NOTE: even though dsos can logically share the same dsts, the IdentityMap
    does not manage DSTs, hence two DSOs in the IdentityMap that logically share the same dst
    could have totally different instances of the logically same DST. 
    '''

    # maps for the dsos
    __dso_map = None
    
    def __init__(self):
        '''
        Constructor
        '''
        self.__dso_map = {}
    
    def get_dso(self, id, version):
        try:
            return self.__dso_map[(id, version)]
        except KeyError:
            raise IdentityMapNotFoundException('Combination of id and version does not exist')
    
    def add_dso(self, dso):
        if dso.id is None or dso.version is None:
            raise IdentityMapException('DSO has no id or version number')
        else:
            self.__dso_map[(dso.id, dso.version)] = dso
            return dso
        
    def remove_dso(self, dso):
        if dso.id is None or dso.version is None:
            raise IdentityMapException('DSO has no id or version number')
        else:
            try:
                del self.__dso_map[(dso.id, dso.version)]
            except KeyError:
                raise IdentityMapNotFoundException('Combination of id and version does not exist')
        
class IdentityMapException(Exception):
    pass

class IdentityMapNotFoundException(IdentityMapException):
    pass